/**
 *  @file: LedTask.h
 *  @author: nwz
 *  @brief: 
 *  @date: 2024��8��1��
 * 
 */

#pragma once
#include <all_header.h>
namespace task {

/*
 *
 */

class LedTask {
public:
	enum class led_state_ops : uint8_t {
		ON, OFF, LOOP, FOREVER_LOOP, CLOSE_FOREVER
	};

	enum class led_state_id : uint8_t {
		NULLID = 0,
		WORK,
		ERROR,
		TIP,
		CLOSE_WORK,
		CLOSE_ERROR,
		DIRECT_ON,
		DIRECT_OFF
	};

	typedef struct {
		const uint8_t id;
		const GPIO_TypeDef *port;
		const uint16_t pin;
		led_state_id state_id;
		led_state_id old_state_id[5];
		uint32_t start_time;
	} led_t;

	typedef struct {
		led_state_id id;
		led_state_ops ops;
		uint8_t led_id;
		uint8_t priority;
		uint8_t loops;
		uint16_t on_duration;
		uint16_t off_duration;
		led_state_id close_id;
	} led_state_t;

public:
	LedTask();
	virtual ~LedTask();
	int setState(led_state_id state, uint32_t wait_timeout = 5000);

	int init();
	static void run(LedTask *task);

private:
	static led_t leds[];
	static const led_state_t states[];

	SemaphoreHandle_t mutex;
	SemaphoreHandle_t sem;

	void saveCurrentState(led_t& led);
	int setState_2(led_state_id state);

	int findOldState(led_t& led,led_state_id state);
	int addOldState(led_t& led,led_state_id state);
	int removeOldState(led_t& led,led_state_id id);
	led_state_id getOldStateId(led_t& led);

	void run_();

	void turnOn(uint8_t led_id) {
		setGpio(led_id, true);
	}
	void turnOff(uint8_t led_id) {
		setGpio(led_id, false);
	}
	void setGpio(uint8_t led_id, bool value) {
		HAL_GPIO_WritePin((GPIO_TypeDef*)leds[led_id].port, leds[led_id].pin,
				value ? GPIO_PIN_SET : GPIO_PIN_RESET);
	}
	uint32_t calculateSleepTick();

};

} /* namespace task */
